/**
 * Copyright 2007 Luke Pillow
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.orsomethinglikethat.hinge.apt;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.orsomethinglikethat.hinge.asgen.meta.MetaClass;
import com.orsomethinglikethat.hinge.asgen.meta.MetaField;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.type.ClassType;

/**
 * @author lpillow
 */
public class APTMetaClass extends MetaClass
{
    private static Logger log = Logger.getLogger( APTMetaClass.class );

    protected static Map<String, APTMetaClass> metaClassCache = new HashMap<String, APTMetaClass>();

    public static APTMetaClass build( ClassDeclaration classDeclaration )
    {
        String qualifiedClassName = classDeclaration.getQualifiedName();
        APTMetaClass result = metaClassCache.get( qualifiedClassName );

        if ( result == null )
        {
            result = new APTMetaClass( classDeclaration.getSimpleName(), classDeclaration.getPackage().toString(), classDeclaration );
            metaClassCache.put( qualifiedClassName, result );
        }

        return result;
    }

    private APTMetaClass( String name, String packageName, ClassDeclaration classDeclaration )
    {
        super( name, packageName );

        this.setSuperclass( classDeclaration.getSuperclass() );
        this.initalizeFields( classDeclaration );
    }

    private void setSuperclass( ClassType superclassType )
    {
        if ( superclassType != null )
        {
            // Don't generate java.lang.Object
            if ( !superclassType.getDeclaration().getQualifiedName().equals( Object.class.getCanonicalName() ) )
            {
                super.setSuperclass( APTMetaClass.build( superclassType.getDeclaration() ) );
                log.debug( "Adding valid superclass:  " + superclassType.getDeclaration().getQualifiedName() );
            }
        }
    }

    private void initalizeFields( ClassDeclaration classDeclaration )
    {
        for ( FieldDeclaration field : HingeCompilerUtil.getValidFields( classDeclaration ) )
        {
            log.debug( "Adding Field: " + this.qualifiedName() + "#" + field.getSimpleName() );
            this.addField( new MetaField( field.getSimpleName(), field.getType().toString(), Boolean.TRUE, Boolean.TRUE ) );
        }
    }
}
